package biz

import (
	"context"
	"fmt"
	"github.com/go-kratos/kratos/v2/log"
	v1 "review-service/api/review/v1"
	"review-service/internal/data/model"
	"review-service/pkg/snowflake"
	"strings"
	"time"
)

type ReviewRepo interface {
	SaveReview(context.Context, *model.ReviewInfo) (*model.ReviewInfo, error)
	GetReviewByOrderID(context.Context, int64) ([]*model.ReviewInfo, error)
	AuditReview(context.Context, *AuditParam) error
	SaveReply(ctx context.Context, reply *model.ReviewReplyInfo) (*model.ReviewReplyInfo, error)
	SaveAppeal(ctx context.Context, appeal *model.ReviewAppealInfo) (*model.ReviewAppealInfo, error)
	CompleteAudit(ctx context.Context, audit *AuditAppealParam) error
	ListReviewByUserID(ctx context.Context, userID int64, offset, limit int) ([]*model.ReviewInfo, error)
	GetReview(context.Context, int64) (*model.ReviewInfo, error)
	ListReviewByStoreID(ctx context.Context, storeID int64, offset, limit int) ([]*MyReviewInfo, error)
}
type ReviewUsecase struct {
	repo ReviewRepo
	log  *log.Helper
}

func NewReviewUsecase(repo ReviewRepo, logger log.Logger) *ReviewUsecase {
	return &ReviewUsecase{repo: repo, log: log.NewHelper(logger)}
}

func (uc *ReviewUsecase) CreateReview(ctx context.Context, review *model.ReviewInfo) (*model.ReviewInfo, error) {
	uc.log.WithContext(ctx).Debug("[biz]CreateReview req:%v", review)
	//1.数据校验
	reviews, err := uc.repo.GetReviewByOrderID(ctx, review.OrderID)
	if err != nil {
		return nil, v1.ErrorDbFailed("连接数据库失败")
	}
	if len(reviews) > 0 {
		fmt.Println("该订单已经评价过了")
		return nil, v1.ErrorOrderReviewed("该%d订单已经评价", review.OrderID)
	}
	//2.生成reviewID
	review.ReviewID = snowflake.GenID()

	//3.查询订单和商品快照
	//4.拼装数据入库
	return uc.repo.SaveReview(ctx, review)
}

func (uc *ReviewUsecase) CreatReply(ctx context.Context, param *ReplyParam) (*model.ReviewReplyInfo, error) {
	uc.log.WithContext(ctx).Debug("[biz]CreateReply req:%v", param)

	//生成replyID
	reply := &model.ReviewReplyInfo{
		ReplyID:   snowflake.GenID(),
		ReviewID:  param.ReviewID,
		StoreID:   param.StoreID,
		Content:   param.Content,
		PicInfo:   param.PicInfo,
		VideoInfo: param.VideoInfo,
	}
	//存入数据库
	//返回数据
	return uc.repo.SaveReply(ctx, reply)

}

func (uc *ReviewUsecase) CreatAppeal(ctx context.Context, appeal *AppealParam) (*model.ReviewAppealInfo, error) {
	uc.log.WithContext(ctx).Debug("[biz]CreateAppeal req:%v", appeal)

	data := &model.ReviewAppealInfo{
		ReviewID:  appeal.ReviewID,
		StoreID:   appeal.StoreID,
		Reason:    appeal.Reason,
		Content:   appeal.Content,
		PicInfo:   appeal.PicInfo,
		VideoInfo: appeal.VideoInfo,
		OpUser:    appeal.OpUser,
	}
	return uc.repo.SaveAppeal(ctx, data)

}

func (uc *ReviewUsecase) CreatAudit(ctx context.Context, audit *AuditAppealParam) error {
	uc.log.WithContext(ctx).Debug("[biz]CreateAudit req:%v", audit)
	err := uc.repo.CompleteAudit(ctx, audit)

	return err
}

func (uc *ReviewUsecase) ListReviewByUserID(ctx context.Context, userID int64, page, size int) ([]*model.ReviewInfo, error) {
	if page <= 0 {
		page = 1
	}
	if size <= 0 || size > 50 {
		size = 10
	}
	offset := (page - 1) * size
	limit := size
	uc.log.WithContext(ctx).Debugf("[biz] ListReviewByUserID userID:%v", userID)
	return uc.repo.ListReviewByUserID(ctx, userID, offset, limit)
}

func (uc *ReviewUsecase) GetReview(ctx context.Context, reviewID int64) (*model.ReviewInfo, error) {
	uc.log.WithContext(ctx).Debugf("[biz] GetReview reviewID:%v", reviewID)
	return uc.repo.GetReview(ctx, reviewID)
}
func (uc *ReviewUsecase) AuditReview(ctx context.Context, param *AuditParam) error {
	uc.log.WithContext(ctx).Debugf("[biz] AuditReview param:%v", param)
	return uc.repo.AuditReview(ctx, param)
}

func (uc *ReviewUsecase) ListReviewByStoreID(ctx context.Context, storeID int64, page, size int) ([]*MyReviewInfo, error) {
	if page <= 0 {
		page = 1
	}
	if size <= 0 || size > 50 {
		size = 10
	}
	offset := (page - 1) * size
	limit := size
	uc.log.WithContext(ctx).Debugf("[biz] ListReviewByStoreID storeID:%v", storeID)
	return uc.repo.ListReviewByStoreID(ctx, storeID, offset, limit)
}

type MyReviewInfo struct {
	ID           int64  `gorm:"column:id;primaryKey;autoIncrement:true;comment:主键" json:"id"`     // 主键
	CreateBy     string `gorm:"column:create_by;not null;comment:创建⽅标识" json:"createBy"`          // 创建⽅标识
	UpdateBy     string `gorm:"column:update_by;not null;comment:更新⽅标识" json:"updateBy"`          // 更新⽅标识
	DeleteAt     MyTime `gorm:"column:delete_at;comment:逻辑删除标记" json:"deleteAt"`                  // 逻辑删除标记
	Version      int32  `gorm:"column:version;not null;comment:乐观锁标记" json:"version"`             // 乐观锁标记
	ReviewID     int64  `gorm:"column:review_id;not null;comment:评价id" json:"reviewId"`           // 评价id
	Content      string `gorm:"column:content;not null;comment:评价内容" json:"content"`              // 评价内容
	Score        int32  `gorm:"column:score;not null;comment:评分" json:"score"`                    // 评分
	ServiceScore int32  `gorm:"column:service_score;not null;comment:商家服务评分" json:"serviceScore"` // 商家服务评分
	ExpressScore int32  `gorm:"column:express_score;not null;comment:物流评分" json:"expressScore"`   // 物流评分
	HasMedia     int32  `gorm:"column:has_media;not null;comment:是否有图或视频" json:"hasMedia"`        // 是否有图或视频
	OrderID      int64  `gorm:"column:order_id;not null;comment:订单id" json:"orderId"`             // 订单id
	SkuID        int64  `gorm:"column:sku_id;not null;comment:sku id" json:"skuId"`               // sku id
	SpuID        int64  `gorm:"column:spu_id;not null;comment:spu id" json:"spuId"`               // spu id
	StoreID      int64  `gorm:"column:store_id;not null;comment:店铺id" json:"storeId"`             // 店铺id
	UserID       int64  `gorm:"column:user_id;not null;comment:⽤户id" json:"userId"`               // ⽤户id
	Anonymous    int32  `gorm:"column:anonymous;not null;comment:是否匿名" json:"anonymous"`          // 是否匿名
	Tags         string `gorm:"column:tags;not null;comment:标签json" json:"tags"`                  // 标签json
	PicInfo      string `gorm:"column:pic_info;not null;comment:媒体信息：图⽚" json:"picInfo"`          // 媒体信息：图⽚
	VideoInfo    string `gorm:"column:video_info;not null;comment:媒体信息：视频" json:"videoInfo"`      // 媒体信息：视频
	/*
		状态:10待审核；20审核通过；30审核
		不通过；40隐藏
	*/
	Status         int32  `gorm:"column:status;not null;default:10;comment:状态:10待审核；20审核通过；30审核\n不通过；40隐藏" json:"status"`
	IsDefault      int32  `gorm:"column:is_default;not null;comment:是否默认评价" json:"isDefault"`           // 是否默认评价
	HasReply       int32  `gorm:"column:has_reply;not null;comment:是否有商家回复:0⽆;1有" json:"hasReply"`      // 是否有商家回复:0⽆;1有
	OpReason       string `gorm:"column:op_reason;not null;comment:运营审核拒绝原因" json:"opReason"`           // 运营审核拒绝原因
	OpRemarks      string `gorm:"column:op_remarks;not null;comment:运营备注" json:"opRemarks"`             // 运营备注
	OpUser         string `gorm:"column:op_user;not null;comment:运营者标识" json:"opUser"`                  // 运营者标识
	GoodsSnapshoot string `gorm:"column:goods_snapshoot;not null;comment:商品快照信息" json:"goodsSnapshoot"` // 商品快照信息
	ExtJSON        string `gorm:"column:ext_json;not null;comment:信息扩展" json:"extJson"`                 // 信息扩展
	CtrlJSON       string `gorm:"column:ctrl_json;not null;comment:控制扩展" json:"ctrlJson"`
	CreateAt       MyTime `json:"createAt"`
	UpdateAt       MyTime `json:"updateAt"`
}

type MyTime time.Time

func (t *MyTime) UnmarshalJSON(data []byte) (err error) {
	if len(data) == 0 || string(data) == "null" {
		*t = MyTime(time.Time{}) // 返回零值时间
		return nil
	}

	s := strings.Trim(string(data), `"`)
	if s == "" {
		*t = MyTime(time.Time{})
		return nil
	}
	return err
}
